﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Wild2.Models.Auth;
using Wild2.Models.Browsers;

namespace Wild2
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.IgnoreRoute("{*alljs}", new { alljs = @".*\.js(/.*)?" });
            routes.IgnoreRoute("{*allgif}", new { allgif = @".*\.gif(/.*)?" });
            routes.IgnoreRoute("{*allcss}", new { allcss = @".*\.css(/.*)?" });
            routes.IgnoreRoute("{*allhtml}", new { allhtml = @".*\.html(/.*)?" });
            routes.IgnoreRoute("{*allswf}", new { allswf = @".*\.swf(/.*)?" });
            routes.IgnoreRoute("{*allswf}", new { allswf = @".*\.ashx(/.*)?" });
            routes.IgnoreRoute("{*allpng}", new { allpng = @".*\.png(/.*)?" });
            routes.IgnoreRoute("{*allpdf}", new { allpdf = @".*\.pdf(/.*)?" });
            routes.IgnoreRoute("{*allcsv}", new { allpdf = @".*\.csv(/.*)?" });
            routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

            routes.MapRoute(
                            "Pages", // Route name
                            "{parameter}.aspx", // URL with parameters
                            new { controller = "Home", action = "Index", parameter = 0 },
                            new { parameter = @"\d+" }
                        );

            routes.MapRoute(
                            "Topic", // Route name
                            "Topic.aspx/Index/{id}", // URL with parameters
                            new { controller = "Topic", action = "Index" }, // Parameter defaults
                            new { id = @"-?\d+" }
                        );

            routes.MapRoute(
                            "SandboxTopic", // Route name
                            "SandboxTopic.aspx/Index/{p}/{id}", // URL with parameters
                            new { controller = "SandboxTopic", action = "Index", p = 1 }, // Parameter defaults
                            new { id = @"-?\d+" }
                        );

            routes.MapRoute(
                            "TopicVote", // Route name
                            "Topic.aspx/Vote/{topic}/{vote}/{hash}", // URL with parameters
                            new { controller = "Topic", action = "Vote" }, // Parameter defaults
                            new { topic = @"\d+", vote = @"-?\d+" }
                        );

            routes.MapRoute(
                            "TopicSandboxVote", // Route name
                            "SandboxTopic.aspx/Vote/{topic}/{vote}/{hash}", // URL with parameters
                            new { controller = "SandboxTopic", action = "Vote" }, // Parameter defaults
                            new { topic = @"\d+", vote = @"-?\d+" }
            );

            routes.MapRoute(
                            "BlogMy", // Route name
                            "Blog.aspx/My/{parameter}", // URL with parameters
                            new { controller = "Blog", action = "My", parameter = 0 }, // Parameter defaults
                            new { parameter = @"\d+" }
                        );

            routes.MapRoute(
                           "BlogUser", // Route name
                           "Blog.aspx/User/{id}/{parameter}", // URL with parameters
                           new { controller = "Blog", action = "User", parameter = 0 }, // Parameter defaults
                           new { id = @"\d+", parameter = @"\d+" }
                       );

            routes.MapRoute(
                            "BlogSandbox", // Route name
                            "Blog.aspx/Sandbox/{parameter}", // URL with parameters
                            new { controller = "Blog", action = "Sandbox", parameter = 0 }, // Parameter defaults
                            new { parameter = @"\d+" }
                        );

            //routes.MapRoute(
            //                "BlogTags", // Route name
            //                "Blog.aspx/Tags/{tag}", // URL with parameters
            //                new { controller = "Blog", action = "Tags" } // Parameter defaults
            //);

            routes.MapRoute(
                            "BlogTop", // Route name
                            "Blog.aspx/All/{parameter}", // URL with parameters
                            new { controller = "Blog", action = "All", parameter = 0 }, // Parameter defaults
                            new { parameter = @"\d+" }
                        );

            routes.MapRoute(
                            "BlogSubscr", // Route name
                            "Blog.aspx/Subscr/{parameter}", // URL with parameters
                            new { controller = "Blog", action = "Subscr", parameter = 0 }, // Parameter defaults
                            new { parameter = @"\d+" }
                        );

            routes.MapRoute(
                        "User", // Route name
                        "User.aspx/Index/{id}", // URL with parameters
                        new { controller = "User", action = "Index" }, // Parameter defaults
                        new { id = @"\d+" }
            );

            routes.MapRoute(
                           "UserVote", // Route name
                           "User.aspx/Vote/{user}/{vote}/{hash}", // URL with parameters
                           new { controller = "User", action = "Vote" }, // Parameter defaults
                           new { user = @"\d+", vote = @"-?\d+" }
           );

            routes.MapRoute(
                        "OfficeAddress", // Route name
                        "Office.aspx/Address/{id}", // URL with parameters
                        new { controller = "Office", action = "Address" }, // Parameter defaults
                        new { id = @"\d+" }
            );

            routes.MapRoute(
                        "FavoritesDelete", // Route name
                        "Favorites.aspx/Delete/{id}", // URL with parameters
                        new { controller = "Favorites", action = "Delete" }, // Parameter defaults
                        new { id = @"\d+" }
            );

            routes.MapRoute(
                "UserTop", // Route name
                "User.aspx/Top/{p}", // URL with parameters
                new { controller = "User", action = "Top", p = 1 }, // Parameter defaults
                new { p = @"\d+" }
            );

            routes.MapRoute(
                "UserSubscr", // Route name
                "User.aspx/Subscr/{id}", // URL with parameters
                new { controller = "User", action = "Subscr" }, // Parameter defaults
                new { id = @"-?\d+" }
            );

            routes.MapRoute(
                            "Default", // Route name
                            "{controller}.aspx/{action}", // URL with parameters
                            new { controller = "Home", action = "Index" }//, // Parameter defaults
                            //new { controller = new NotEqual("Help|Info") }
                            //new { controller = new NotEqual("Info") }
                        );

        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
            Application["datestart"] = DateTime.Now;
        }

        protected void Application_End(object sender, EventArgs e)
        {
            //  Code that runs on application shutdown
        }

        protected void Application_Error(object sender, EventArgs e)
        {
            Exception exc = Server.GetLastError();
            Int32? userId = null;
            Object o = HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            Models.Logger.Log(exc, userId);
        }

        protected void Session_Start(object sender, EventArgs e)
        {
            Session.Add(Wild2.Models.Constants.SessionConstants.GUID, Guid.NewGuid().ToString().Substring(0, 4));
            BrowserSelector.BrowserClass bc = new BrowserSelector().GetVersionFromBrowser(Request.UserAgent);
            Session.Add(Wild2.Models.Constants.SessionConstants.VERSION, bc.Version);
            Session.Add(Wild2.Models.Constants.SessionConstants.FONTSIZE, bc.FontSize);
            //Session.Add("Culture", Models.GeoIP.GeoIP.GetLocale()); //LOCALE
        }

        protected void Session_End(object sender, EventArgs e)
        {
            Int32? userId = null;
            Object o = Session[Wild2.Models.Constants.SessionConstants.USERID];
            if (o != null) userId = Convert.ToInt32(o);
            if (userId.HasValue)
            {
                Object oo = Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_TIMESPAN];
                if (oo != null)
                {
                    TimeSpan timeOnSiteTimeSpan = (TimeSpan)oo;
                    Models.TimeOnSite.TimeOnSite.UpdateTimeOnSite(userId.Value, timeOnSiteTimeSpan);
                }
            }
        }

        void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Application["gentime"] = DateTime.Now;
        }

        void Application_AcquireRequestState(object sender, EventArgs e)
        {
            string host = ConfigurationManager.AppSettings["domainshort"];
            if ((Request.Url.Host.IndexOf(host, StringComparison.Ordinal) == -1) || (Request.Url.Host.IndexOf("wap." + host, StringComparison.Ordinal) >= 0) || (Request.Url.Host.IndexOf("www." + host, StringComparison.Ordinal) >= 0))
            {
                var newUrl = new UriBuilder(ConfigurationManager.AppSettings["domain"] + Request.RawUrl.ToLower().Replace("default.aspx", ""));
                newUrl.Host = host;
                Response.StatusCode = 301;
                Response.Status = "301 Moved Permanently";
                Response.AddHeader("Location", newUrl.Uri.AbsoluteUri);
                Response.End();
            }
        }

        void Application_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            if (Context.Handler is System.Web.SessionState.IRequiresSessionState)
            {
                //LOCALE
                //String locale = Session[Wild2.Models.Constants.SessionConstants.CULTURE] as String;
                //if(!String.IsNullOrEmpty(locale))
                //{
                //    if (locale != "default")
                //    {
                //        System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(locale, false);
                //        System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(locale, false);
                //    }
                //}
                //if (HttpContext.Current.Request.Path.ToLower().IndexOf("favorites") == -1) HttpContext.Current.Session[Wild2.Models.Constants.SessionConstants.FAVORITES] = HttpContext.Current.Request.Path;
                Int32? userId = AuthOnSite.GetUserId();
                if (!userId.HasValue)
                {
                    HttpCookie httpCookie = HttpContext.Current.Request.Cookies["PrivateKey"];
                    if (httpCookie != null)
                        AuthOnSite.AuthGUID(httpCookie.Value);
                }
                else
                {
                    Object timeOnSiteDate = Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_DATE];
                    if (timeOnSiteDate != null)
                    {
                        DateTime dt = (DateTime)Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_DATE];
                        TimeSpan ts = DateTime.Now.Subtract(dt);
                        TimeSpan timeOnSiteTimeSpan = (TimeSpan)Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_TIMESPAN];
                        timeOnSiteTimeSpan = timeOnSiteTimeSpan.Add(ts);
                        Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_TIMESPAN] = timeOnSiteTimeSpan;
                        Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_DATE] = DateTime.Now;
                        //HttpContext.Current.Response.Write(TimeOnSiteTimeSpan.TotalSeconds);
                    }
                    else
                    {
                        Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_DATE] = DateTime.Now;
                        Session[Wild2.Models.Constants.SessionConstants.TIME_ON_SITE_TIMESPAN] = new TimeSpan(0);
                    }
                    Models.TimeOnSite.TimeOnSite.UpdateLastDateOnSite(userId.Value);
                }
                try
                {
                    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectStatistic"].ConnectionString))
                    {
                        using (SqlCommand cmd = new SqlCommand("INSERT INTO [UsersLog]([IP], [XIP], [UserAgent], [date], [Page], [UserID], [SessionString]) VALUES(@IP, @XIP, @UA, GETDATE(), @Page, @UID, @Session)", conn))
                        {
                            cmd.Parameters.Add("@IP", System.Data.SqlDbType.NVarChar, 20).Value = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
                            if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) cmd.Parameters.Add("@XIP", System.Data.SqlDbType.NVarChar, 20).Value = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                            else cmd.Parameters.Add("@XIP", System.Data.SqlDbType.NVarChar, 20).Value = DBNull.Value;
                            if (HttpContext.Current.Request.UserAgent != null) cmd.Parameters.Add("@UA", System.Data.SqlDbType.NVarChar, 200).Value = HttpContext.Current.Request.UserAgent;
                            else cmd.Parameters.Add("@UA", System.Data.SqlDbType.NVarChar, 200).Value = DBNull.Value;
                            //cmd.Parameters.Add("@Page", System.Data.SqlDbType.NVarChar, 200).Value = Request.RawUrl;
                            cmd.Parameters.Add("@Page", System.Data.SqlDbType.NVarChar, 200).Value = Request.Url.ToString();
                            if (userId.HasValue) cmd.Parameters.Add("@UID", System.Data.SqlDbType.Int).Value = userId.Value;
                            else cmd.Parameters.Add("@UID", System.Data.SqlDbType.Int).Value = DBNull.Value;
                            cmd.Parameters.Add("@Session", System.Data.SqlDbType.NVarChar, 50).Value = Session.SessionID;
                            cmd.Connection.Open();
                            cmd.ExecuteNonQuery();
                            cmd.Connection.Close();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Models.Logger.Log(ex, null);
                }
                //Расчет сколько занимает сессия
                //if (Context.Handler is System.Web.SessionState.IRequiresSessionState)
                //{
                //    long totalBytes = 0;
                //    var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                //    for (int i = 0; i < Session.Count; i++)
                //    {
                //        using (var stream = new System.IO.MemoryStream())
                //        {
                //            formatter.Serialize(stream, Session[i]);
                //            stream.Flush();
                //            totalBytes += stream.Length;
                //        }
                //    }
                //    HttpContext.Current.Response.Write(totalBytes);
                //}
            }
        }

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            //Не работает после сжатия
            //DateTime dt = (DateTime)HttpContext.Current.Application["gentime"];
            //HttpContext.Current.Response.Write(String.Format("\r\n\r\n<!-- {0} c. -->", DateTime.Now.Subtract(dt).TotalSeconds));
        }

        protected void Application_PostRequestHandlerExecute(object sender, EventArgs e)
        {
            DateTime dt = (DateTime)HttpContext.Current.Application["gentime"];
            HttpContext.Current.Response.Write(String.Format("\r\n\r\n<!-- {0} c. -->", DateTime.Now.Subtract(dt).TotalSeconds));
        }
    }
}